//
//  ASJStage.m
//  ASJ001
//
//  Created by zephyrhan on 11/13/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "ASJStage.h"
#import "ASJActor.h"
#import "ASJMonster.h"
#import "ASJGlobalDefine.h"
#import "ASJSkillMonsterAttack.h"
#import "ASJGestureRecoginzer.h"


#define MOUNTAIN_Y      (160.0  / 320.0)
#define GROUND_Y        (40.0   / 320.0)
#define CLOUD_Y         (240.0  / 320.0)
#define GRASS_Y         (65.0   / 320.0)
#define OBJECT_Y        (95.0   / 320.0)


@interface ASJStage (PrivateMethods)

- (void)setupStageEnvironment;
- (void)setupActor;

@end

@implementation ASJStage
@synthesize stageName, theActor, firstMonster, monsters, worldLayer, maskLayer, winSize, targetPosition, startAddMonster, gestureRecognizer;
@synthesize cloud, cloudX, grass, grassX, ground, groundX, mountain, mountainX;

- (id)initWithStageName:(NSString*)name {
    assert([name length] > 0);
    
    if ((self = [super init])) {
        stageName = [name retain];
        
        theActor = [[ASJActor alloc] init];
        
        monsters = [[NSMutableArray alloc] initWithCapacity:20];
        
        targetPosition = CGPointMake(40, 95);
        startAddMonster = NO;
    }

    return self;
}


- (void)dealloc {
    [stageName release];
    [worldLayer release];
    [monsters release];

    [super dealloc];
}


- (void)setupStageInLayer:(CCLayer*)layer {
    worldLayer = [layer retain];
    
    [self setupStageEnvironment];
    [self setupActor];
}


- (void)setupActor 
{
    theActor.worldLayer = worldLayer;
    theActor.worldStage = self;
    [theActor loadSkills];
}


-(void)setupStageEnvironment
{
    CCSprite* bg = [CCSprite spriteWithFile:[NSString stringWithFormat:@"%@_bg.png", stageName]];      
    [bg setPosition: worldPos(0.5, 0.5)];
    bg.scale = 2.0;
    [worldLayer addChild:bg];
    
//    CCLOG(@"bg content is %f", bg.contentSize.width);
    
    CCSpriteBatchNode* bgBatchNode = [CCSpriteBatchNode batchNodeWithFile:[NSString stringWithFormat:@"%@.png", stageName]];
    [worldLayer addChild:bgBatchNode];
    CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
    [frameCache addSpriteFramesWithFile:[NSString stringWithFormat:@"%@.plist", stageName]];
    
    
    //mountain
    CCSpriteFrame* frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_mountain.png", stageName]];
    mountain = [CCSprite spriteWithSpriteFrame:frame];
    mountain.position  =  worldPos(0.5, MOUNTAIN_Y);
    mountain.scaleX = 1.2f;
    [bgBatchNode addChild:mountain];
 
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_mountain.png", stageName]];
    mountainX = [CCSprite spriteWithSpriteFrame:frame];
    mountainX.position =  worldPos(1.5, MOUNTAIN_Y);
    mountainX.flipX = YES;
    [bgBatchNode addChild:mountainX];
    
    //cloud
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_cloud.png", stageName]];
    cloud = [CCSprite spriteWithSpriteFrame:frame];
    cloud.position =  worldPos(0.5, CLOUD_Y);
    [bgBatchNode addChild:cloud];
    
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_cloud.png", stageName]];
    cloudX = [CCSprite spriteWithSpriteFrame:frame];
    cloudX.position =  worldPos(1.5, CLOUD_Y);
    [bgBatchNode addChild:cloudX];
        
    //grass
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_grass.png", stageName]];
    grass = [CCSprite spriteWithSpriteFrame:frame];
    grass.scaleX = 1.2f;
    grass.position =  worldPos(0.5, GRASS_Y);
    [bgBatchNode addChild:grass];

    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_grass.png", stageName]];
    grassX = [CCSprite spriteWithSpriteFrame:frame];
    grassX.scaleX = 1.2f;
    grassX.flipX = YES;
    grassX.position =  worldPos(1.5, GRASS_Y);
    [bgBatchNode addChild:grassX];
    
    //ground
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_ground.png", stageName]];
    ground = [CCSprite spriteWithSpriteFrame:frame];
    ground.position =  worldPos(0.5, GROUND_Y);
    ground.scaleX = 1.2f;
    [bgBatchNode addChild:ground];
    
    frame = [frameCache spriteFrameByName:[NSString stringWithFormat:@"%@_ground.png", stageName]];
    groundX = [CCSprite spriteWithSpriteFrame:frame];
    groundX.position =  worldPos(1.5, GROUND_Y);
    [bgBatchNode addChild:groundX];
}


- (void)start 
{
    assert(worldLayer != nil);
    
    [theActor runSkillByName:@"actor_walk" frameCount:6];
    theActor.position = worldPos(-0.1, OBJECT_Y);
    
    CCMoveTo* moveTo = [CCMoveTo actionWithDuration:2.0 position:worldPos(0.1, OBJECT_Y)];
    CCCallFunc* func = [CCCallFunc actionWithTarget:self selector:@selector(actorReady)];
    [theActor.currentSkill.skillSprite runAction:[CCSequence actions:moveTo, func, nil]];
}


- (void)stop {

}


- (void)actorReady {
    [self performSelectorInBackground:@selector(birthMonster) withObject:nil];    
}


- (void)birthMonster
{
//    1，主角开始前进，画面滚动
//    2,二秒后出现第一只怪（怪1-床单怪）
//    3，10秒为一个单位时间，单位时间内刷10只怪（速度随机），每个单位之间间隔3秒不刷怪。（游戏开始-10秒刷怪时间-3秒不刷怪-10秒刷怪时间……）
//    4，第一关共有5次刷怪，即50只怪。在全部消灭后，进入BOSS脚本，背景音乐停止播放，主角前进3秒，刷出BOSS1场景物件，全部显示后，主角停止移动，播放待机动画，BOSS1出生动画，动画结束，BOSS1进入待机动画，背景音乐播放，脚本结束。BOSS战开始
//    6，BOSS血量为0，进入BOSS1死亡脚本，背景音乐停止播放，播放BOSS死亡动画，动画结束-过关音乐播放，主角走到屏幕中间做胜利动作，最后一帧停留2秒，前进，场景物件【瓶子】进入画面（主角还是在中间位置，瓶子在屏幕右侧）
//    7，关着NPC的瓶子完全出现在画面右侧，主角停止前进-待机-瓶子中的NPC在瓶子内四处飘动，然后回到原位-主角施法动作，停留在最后一帧-瓶塞从瓶口蹦出-主角恢复待机动作-NPC从瓶口飘出，飘到主角身边-跳出确认按钮，询问是否进入下一关。做出选择后，确认按钮消失，画面变暗淡出，进入下一关或回到主界面。
//    
    [NSThread sleepForTimeInterval:2];
    
    CGFloat sumTime = 0.0;
    CGFloat randTime = 0.0;
    
    for (int i = 0; i < 5; ++i) { // 5
        for (int j = 0; j < 10; ++j) { // 10
            randTime = CCRANDOM_0_1() + 2.0;
            [NSThread sleepForTimeInterval:randTime];
            sumTime += randTime;
            
            // birth a monster
            ASJMonster* monster = [[ASJMonster alloc] init];
            monster.movingSpeed = CGPointMake(-1.0, 0.0);
            monster.HP = 20;
            monster.attackRate = 1;
            monster.attackRange = 60.0;
            
            monster.currentHP = monster.HP;
            monster.currentAttackRate = monster.attackRate;
            monster.currentMovingSpeed = monster.movingSpeed;
            
            monster.worldLayer = worldLayer;
            monster.worldStage = self;

            { // loadskill
                ASJSkill* walk = [[ASJSkill alloc] initWithSkillName:@"goast_walk" frameCount:6 inStage:self];
                [monster setSkill:walk forName:@"goast_walk"];
                
                ASJSkill* stand = [[ASJSkill alloc] initWithSkillName:@"goast_stand" frameCount:6 inStage:self];
                [monster setSkill:stand forName:@"goast_stand"];
        
                ASJSkill* attack = [[ASJSkillMonsterAttack alloc] initWithSkillName:@"goast_attack" frameCount:6 inStage:self];
                attack.skillPowser = 1.0;
                attack.coolTime = 1.0;
                [monster setSkill:attack forName:@"goast_attack"];
            }

            [monster runSkillByName:@"goast_walk"];
            monster.position = worldPos(1.0, 0.4);

            [monsters performSelectorOnMainThread:@selector(addObject:) withObject:monster waitUntilDone:YES];

            if (firstMonster == nil) {
                firstMonster = monster;
            }
        }

        [NSThread sleepForTimeInterval:MAX((30.0 - sumTime), 0) + 10];
        sumTime = 0;
    }
    
    while ([monsters count] > 0) {
        [NSThread sleepForTimeInterval:3];
    }

    // TODO: BOSS
}


-(void)backgroundMove
{
    static CGFloat cloudSpeed = 30.0 / 60.0;
    static CGFloat groundSeppd = 60.0 / 60.0;
    
    // cloud moving
    if (cloud.position.x < winX(-0.5)) {
        cloud.position = worldPos(1.5, CLOUD_Y);
    }
    if (cloudX.position.x < winX(-0.5)) {
        cloudX.position =  worldPos(1.5, CLOUD_Y);
    }
    cloud.position = ccpSub(cloud.position, CGPointMake(cloudSpeed, 0));
    cloudX.position = ccpSub(cloudX.position, CGPointMake(cloudSpeed, 0));
    
    
    if ([monsters count] > 0) {
        return ;
    }
    
    if (mountain.position.x < winX(-0.5)) {
        mountain.position = worldPos(1.5, MOUNTAIN_Y);
    }
    if (mountainX.position.x < winX(-0.5)) {
        mountainX.position = worldPos(1.5, MOUNTAIN_Y);
    }
    
    if (ground.position.x < winX(-0.5)) {
        ground.position =  worldPos(1.5, GROUND_Y);
    }
    if (groundX.position.x  < winX(-0.5)) {
        groundX.position =  worldPos(1.5, GROUND_Y);
    }
    
    if (grass.position.x < winX(-0.5)) {
        grass.position = worldPos(1.5, GRASS_Y);
    }
    if (grassX.position.x < winX(-0.5)) {
        grassX.position =  worldPos(1.5, GRASS_Y);
    }

    mountain.position = ccpSub(mountain.position, CGPointMake(groundSeppd, 0));
    mountainX.position = ccpSub(mountainX.position, CGPointMake(groundSeppd, 0));
    ground.position = ccpSub(ground.position, CGPointMake(groundSeppd, 0));
    groundX.position = ccpSub(groundX.position, CGPointMake(groundSeppd, 0));
    grass.position = ccpSub(grass.position, CGPointMake(groundSeppd, 0));
    grassX.position = ccpSub(grassX.position, CGPointMake(groundSeppd, 0));
    
    stageDistance += groundSeppd;
}


-(void)gameStep
{
    if ([monsters count] > 0) {
        for (ASJMonster* monster in monsters) {
            int dist = abs(monster.position.x - theActor.position.x);
            if (dist < monster.attackRange) {
                if ([monster runSkillByName:@"goast_attack"] == ASJRUNSKILLRET_COOLING) {
                    [monster runSkillByName:@"goast_stand"];
                }
            } else {
                // run
                [monster runSkillByName:@"goast_walk"];
                [monster setPosition:ccpAdd([monster position], monster.currentMovingSpeed)];
            }
        }

        [theActor runSkillByName:@"actor_stand"];
    } else {
        [theActor runSkillByName:@"actor_walk"];
    }
}


- (void)stopGestureRecognize {
    
}


- (void)startGestureRecognize {
    
}


@end
